
#ifndef _SYSI_
#define _SYSI_
#include "Message_Processing.h"
#include "sys_profile.h"
typedef struct TimerType
{
	uint32 cid;
	uint32 time;
	struct TimerType *next;
}TMRT;
typedef struct TimerArray
{
	uint32 type;
	TMRT *timer;
	struct TimerArray *next;
}TMRA;
TMRA *timerAT;
typedef struct Qos_Info_Priority
{
	uint32 service_type;
	uint32 priority;
}QIP;
typedef struct CID_List
{
	uint16 cid;
	struct CID_List *next;
}CIDList;


typedef struct BandWidthRequestList
{
	uint32 bytes;
	uint32 cid;
	uint32 cdmaCode;
	uint32 usr;
	enum BWRType BWRtype;
	struct BandWidthRequestList *next;
}BWRList;
typedef struct UL_Queues
{
	QIP *qosInfoPrio[5];
	uint32 isQempty[5];
	uint32 totSlotsInCltQ;
	BWRList *ugsQ;
	BWRList *rtpsQ;
	BWRList *nrtpsQ;
	BWRList *bsQ;
	BWRList *cltQ;
	//MDQ *ugsSDUQ;//collect all unscheduled SDU belong to this usr
	//MDQ *rtpsSDUQ;//collect all unscheduled SDU belong to this usr
	//MDQ *nrtpsSDUQ;//collect all unscheduled SDU belong to this usr
	//MDQ *bsSDUQ;//collect all unscheduled SDU belong to this usr

}ULQS;
typedef struct CID_Group
{
	uint32 BscCID;
	uint32 PmyCID;
	CIDList *TptUGSCID;
	CIDList *TptRTPSCID;
	CIDList *TptNRTPSCID;
	CIDList *TptBSCID;
}CG;

typedef struct DL_Queues
{
	QIP *qosInfoPrio[4];//[0]:UGS [1]:RTPS [2]:NRTPS [3]:BS  set priority 
	uint32 isQempty[4]; //if Qos Queue is empty than it will be set one [0]:UGSQ [1]:RTPSQ [2]:NRTPSQ [3]:BSQ
	uint32 totSlotsInPduQ;

	MDQ *ugsQ;//collect all unscheduled SDU belong to this usr
	MDQ *rtpsQ;//collect all unscheduled SDU belong to this usr
	MDQ *nrtpsQ;//collect all unscheduled SDU belong to this usr
	MDQ *bsQ;//collect all unscheduled SDU belong to this usr
	MDQ *pduQ;//collect scheduled PDUs and Msg belong to this usr .After it ,it will form a DL Burst
	MDQ *msgQ;//collect completed Msgs from control plane
	SDQ *burstQ; //collect completed PDUs to be a usr burst
}DLQS;

typedef struct SS_Info
{
	CG cidGroup;
	uint16 UIUC;
	uint16 DIUC;
	ULQS ulQueues;
	DLQS dlQueues;

}SI;
typedef struct CID_INFO_Table
{
	uint32 CID;
	uint32 Usr;
	struct CID_INFO_Table *left,*right;
}CIT;
typedef struct CID_MDQ_INFO_Table
{
	uint32 CID;
	MDQ *mdqptr;
	struct CID_MDQ_INFO_Table *left,*right;
}CMIT;
typedef struct CID_Mapping_Table
{
	CIT *Bsc;
	CIT *Pmy;
	CIT *TptUGS;
	CIT *TptRTPS;
	CIT *TptNRTPS;
	CIT *TptBS;
}CMT;
typedef struct Map_Usr_2_MS_Info
{
	SI *usrAddr[MAXUSER];
	uint32 usrCount;
}MU2MI;
typedef struct D_UIUC_LookUpTable
{
	uint32 modulation;
	uint32 rateUp;
	uint32 rateDown;
}DUIUCT;
typedef struct System_Msg_Info
{
	uint8 *ptr;
	uint32 tot_bytes;
	uint32 msg_type;
	uint16 cid;
	struct System_Msg_Info *next;
}SMI;

typedef struct System_Queues
{
	ULMAP ulmap_TX;//the ULMAP structures after UL schedule and before Form ULMAP 
	DLMAP dlmap_TX;
	MDQ *bfSchSDUL;//before scheduled and all the sdu and mdq are queue in here
	MDQ *broadcastQ;//collect broadcast Messages like ULMAP DCD UCD and so on
	MDQ *pduQ;
	SDQ *burstQ;
	uint32 totSlotsInPduQ;
}SYSQ;
typedef struct System_Info
{
	DUIUCT tableUIUC[10];//UIUC table
	DUIUCT tableDIUC[10];//DIUC table
	uint32 sysULSlots;//system information that represent UL slots that the system can use
	uint32 sysDLSlots;//system information that represent DL slots that the system can use
	uint32 dlMsgQEmptCount;
	uint32 dlSrvQEmptCount;
	uint32 ulSrvQEmptCount;
	uint32 dlSlotPos;
	CMIT   *rmdPDUCMIT;//after fragment and there are some pdu that is not finished and it will return to here ;note:usr represent mdq's address 
	SYSQ sysQ;
}SYSI;


SCID_List *scid;

SYSI sys;
MU2MI tableMU2MI;
CMT tableCMT;
uint32 sysframe;
FILE*   InFileUsr1;
FILE*   OutFileUsr1;

void Form_Burst(SDQ **,MDQ **);
void InitMsgTLVTable();
void Init_PDUQ(MDQ **pduQ,MDQ *sdul);
void Init_GMHType(GMHType *);
void Init_Header(Header *);
void InitCMT(CMT *table);

void ULSchedulerMain(BWRList *);
void DLSchedulerMain();
MDQ *Construct_Burst(MDQ **,MDQ **,uint32);

void Append_DMPIE_List(DLMAP_IE **,DMP_Ext_DIUC *,uint16 );
void Append_MDQ(MDQ **,SDQ *,uint32 ,uint32 ,uint32  ,uint32 );

int InsCID2CMIT(CMIT **,uint32  ,MDQ **);

void MoveMDQ(MDQ **,MDQ **);

void AddCMT(CMT *,enum CID_Type ,uint32 );
BWRList* AddBWRList(BWRList **ptr);

void SrhCMT(CMT *,uint32 ,uint32 *,uint32 *);
MDQ *SrhBTMdqPtrByLp(CMIT * ,uint32 );

void shakersort(QIP **,uint32 );

void CollectMsgCDMAIE(MsgList *,uint16 *);
uint32 Compare_CRC(uint8 *,uint32 );
uint32 Acc_PQLength(MDQ *);

void DeformatMain();
void DeformatUsrBurst(SDQ *,MsgList **,BWRList **);
void DeformatBroadcastBurst(SDQ *,MsgList **);

void DeleteCMIT(CMIT **,uint32 );
void Delete_DataQ_DList(SDQ *);
void Delete_PDUQ(MDQ **PTR);

//----added
void InitSysInfo();
void CollectMsgBWR(BWRList **t,BWRList *);
void FromMsgQ2MsgList(MsgList *,MsgQ *);

void Format2Burst();
void SetMsgCDMACode(MMSG **,int );
void RESETTimer(uint32 ,uint32 );
void SETTime(uint32 ,uint32 );
void STOPTimer(uint32 ,uint32 );
MsgList * isCDMACodeCollision(MsgList * ,MMSG *);
void ProcAllRSPMsg(MsgList **msglist,int tag);
void ProcALLMMsgBS(MsgList *msglist,int *tag);
void FormatMsg2SysMsgQ(MsgList *msglist);
void Insert_SDQ(SDQ **,uint32 *,uint32,enum STATUS );
SDQ * TransmitUsrBurst(SDQ **burst);
SDQ * TransmitBroBurst();
void InitMU2MI();
void AppendCID();
void Delete_SDQ(SDQ **ptr);
uint32 CalDLRsUnitSlot(uint32 diuc ,uint32 bytes);
void ForceToBeAPDU(SYSQ *dlqs,uint16 cid,uint32 diuc);
void BreakAndLink(SDQ **headPtr,SDQ **tailPtr);
#endif